#ifndef _mpi_data
#define _mpi_data
#include "particles.h"
#include "common.h"
#include "type.h"
#include "mpi.h"
#include "stddef.h"
#include "cellinf.h"

/// 提交三个MPI数据类型,用于传输粒子，场和cell内部场信息
void mpi_type_commit(MPI_Datatype& pline_type, MPI_Datatype& fline_type, MPI_Datatype& jline_type)
{
    __Pline temppline;
    __Fline tempfline;
    __Jline tempjline;
    const int nPItems = 3, nFItems = 2, nJItems = 1;
    int Pblocklen[nPItems] = {1, 2, 14};
    int Fblocklen[nFItems] = {2, 10};
    int Jblocklen[nJItems] = {4};
    MPI_Datatype Ptypes[nPItems] = {MPI_INT, MPI_LONG, MPI_DOUBLE};
    MPI_Datatype Ftypes[nFItems] = {MPI_LONG, MPI_DOUBLE};
    MPI_Datatype Jtypes[nJItems] = {MPI_DOUBLE};
    MPI_Datatype MPI_PType_proto, MPI_FType_proto, MPI_JType_proto;
    // 由于vector本身不同于数组，会存在伸展，因此直接发送会有问题
    MPI_Aint Poffsets[nPItems], Foffsets[nFItems], Joffsets[nJItems];
    Poffsets[0] = offsetof(__Pdata, sp);
    Poffsets[1] = offsetof(__Pdata, id_wt);
    Poffsets[2] = offsetof(__Pdata, vel_pos_ek);
    Foffsets[0] = offsetof(__Fdata, pos);
    Foffsets[1] = offsetof(__Fdata, data);
    Joffsets[0] = offsetof(__Jdata, data);
    MPI_Type_create_struct(nPItems, Pblocklen, Poffsets, Ptypes, &MPI_PType_proto);
    MPI_Type_create_struct(nFItems, Fblocklen, Foffsets, Ftypes, &MPI_FType_proto);
    MPI_Type_create_struct(nJItems, Jblocklen, Joffsets, Jtypes, &MPI_JType_proto);

    // 原始vector的结构体

    MPI_Aint Plb, Pextent, Flb, Fextent, Jlb, Jextent;
    MPI_Type_get_extent(MPI_PType_proto, &Plb, &Pextent);
    MPI_Type_get_extent(MPI_FType_proto, &Flb, &Fextent);
    MPI_Type_get_extent(MPI_JType_proto, &Jlb, &Jextent);
    // 获取上下界，伸展

    Pextent = (char*) &temppline[1] - (char*) &temppline[0];
    Fextent = (char*) &tempfline[1] - (char*) &tempfline[0];
    Jextent = (char*) &tempjline[1] - (char*) &tempjline[0];
    // 计算伸展

    MPI_Type_create_resized(MPI_PType_proto, Plb, Pextent, &pline_type);
    MPI_Type_create_resized(MPI_FType_proto, Flb, Fextent, &fline_type);
    MPI_Type_create_resized(MPI_JType_proto, Jlb, Jextent, &jline_type);
    // 重新计算空间
    MPI_Type_commit(&pline_type);
    MPI_Type_commit(&fline_type);
    MPI_Type_commit(&jline_type);

}

void mpi_type_free(MPI_Datatype& __Pline, MPI_Datatype& __Fline)
{
    MPI_Type_free(&__Pline);
    MPI_Type_free(&__Fline);
}

/// 对与myrank进行数据交换，如果是第一个rank（0），只能向右发送，接收右边数据, 如果是倒数第一个rank只能向左发送,接收左边数据

/// 还是应该把对粒子和场的交换数据分开进行，这样有更大的灵活度
void mpi_exchange_current_lr(const int& myrank, const int& ranksize, __Simbox& mybox,\
        long data_tags[], MPI_Status& status)
{
    if(ranksize < 2)
    {
        return;
    }
        int rank_per_row = ranksize;
        int rankxi = myrank % rank_per_row, rankyj = myrank / rank_per_row;
        int rank_all_row = ranksize / rank_per_row;
        int myleft = myrank - 1, myright = myrank + 1;
        int myup = myrank +  rank_per_row;
        int mydown = myrank - rank_per_row; 
        MPI_Datatype MPI_Fline, MPI_Jline, MPI_Pline;
        mpi_type_commit(MPI_Pline, MPI_Fline, MPI_Jline);
        long S_data_size[8] = {};
        
        __Jline S_myj_linel, S_myj_liner;
        // 0， 1 代表沿x，y方向
        mybox.copy_to_jline(S_myj_linel, S_myj_liner, 0);
       
        // 次序：左，右，下，上
        S_data_size[1] = S_myj_linel.size();
        S_data_size[3] = S_myj_liner.size();
        // 接收
        // 也是先左，后右
        long R_data_size[8] = {};
        __Jline R_myj_linel, R_myj_liner;
        //cout<<myrank<<" sending size\
        // 向左两个
        if(rankxi > 0)
        {
        
            //cout<<myrank<<"lr send to  "<<myleft<<endl;
            MPI_Send(&S_data_size[1], 1, MPI_LONG, myleft, data_tags[1], MPI_COMM_WORLD);
            MPI_Send(&S_myj_linel.front(), S_data_size[1], MPI_Jline, \
                    myleft, data_tags[3], MPI_COMM_WORLD);
            //cout<<myrank<<"lr send to  over "<<myleft<<endl;
            
        }
        
        // 接收右边发过来，是右边发给左边的
        if(rankxi < rank_per_row - 1)
        {
            //cout<<myrank<<"lr receiving "<<myright<<endl;
            MPI_Recv(&R_data_size[3], 1, MPI_LONG, myright, data_tags[1], MPI_COMM_WORLD, &status);
            
            R_myj_liner.resize(R_data_size[3]);
       
            MPI_Recv(&R_myj_liner.front(), R_data_size[3], MPI_Jline, \
                    myright, data_tags[3], MPI_COMM_WORLD, &status);
            //cout<<myrank<<"lr receiving complete "<<myright<<endl;
        }

        
        if(rankxi < rank_per_row - 1)
        {
            // 向右 3 * 2 个
            /// 先发送数据大小，再发送数据 
            //cout<<myrank<<"lr send to  "<<myright<<endl;
            MPI_Send(&S_data_size[3], 1, MPI_LONG, myright, data_tags[5], MPI_COMM_WORLD);
            MPI_Send(&S_myj_liner.front(), S_data_size[3], MPI_Jline, \
                    myright, data_tags[7], MPI_COMM_WORLD);
            //cout<<myrank<<"lr send to  over "<<myright<<endl;
        }
         
        // 接收左边发来的，是左边发给右边的
        if(rankxi > 0)
        {
            //cout<<myrank<<"lr recving "<<myleft<<endl;
            MPI_Recv(&R_data_size[1], 1, MPI_LONG, myleft, data_tags[5], MPI_COMM_WORLD, &status);

            //cout<<"data size receiving "<<R_data_size[0]<<endl<<R_data_size[1]<<endl;
            
            R_myj_linel.resize(R_data_size[1]);
            //cout<<" resizing complete "<<endl;
            
            MPI_Recv(&R_myj_linel.front(), R_data_size[1], MPI_Jline, \
                    myleft, data_tags[7], MPI_COMM_WORLD, &status);
            //cout<<myrank<<"lr recving complete "<<myleft<<endl;
        }
        
        
        mybox.jline_copy_to(R_myj_linel, R_myj_liner, 0);
        clear_vec(S_myj_linel);
        clear_vec(S_myj_liner);
        clear_vec(R_myj_linel);
        clear_vec(R_myj_liner);
        MPI_Type_free(&MPI_Pline);
        MPI_Type_free(&MPI_Fline);
        MPI_Type_free(&MPI_Jline);
}



void mpi_exchange_fields_lr(const int& myrank, const int& ranksize, __Simbox& mybox,\
        long data_tags[], MPI_Status& status)
{
    if(ranksize < 2)
    {
        return;
    }
        int rank_per_row = ranksize;
        int rankxi = myrank % rank_per_row, rankyj = myrank / rank_per_row;
        int rank_all_row = ranksize / rank_per_row;
        int myleft = myrank - 1, myright = myrank + 1;
        int myup = myrank +  rank_per_row;
        int mydown = myrank - rank_per_row; 
        MPI_Datatype MPI_Fline, MPI_Jline, MPI_Pline;
        mpi_type_commit(MPI_Pline, MPI_Fline, MPI_Jline);
        long S_data_size[8] = {};
        
        __Fline S_myfield_linel, S_myfield_liner;
        // 0， 1 代表沿x，y方向
        mybox.copy_to_fline(S_myfield_linel, S_myfield_liner, 0);
       
        // 次序：左，右，下，上
        S_data_size[0] = S_myfield_linel.size();
        S_data_size[2] = S_myfield_liner.size();
        // 接收
        // 也是先左，后右
        long R_data_size[8] = {};
        __Fline R_myfield_linel, R_myfield_liner;
        //cout<<myrank<<" sending size\
        // 向左两个
        if(rankxi > 0)
        {
        
            //cout<<myrank<<"lr send to  "<<myleft<<endl;
            MPI_Send(&S_data_size[0], 1, MPI_LONG, myleft, data_tags[0], MPI_COMM_WORLD);
            MPI_Send(&S_myfield_linel.front(), S_data_size[0], MPI_Fline, \
                    myleft, data_tags[2], MPI_COMM_WORLD);
            //cout<<myrank<<"lr send to  over "<<myleft<<endl;
            
        }
        
        // 接收右边发过来，是右边发给左边的
        if(rankxi < rank_per_row - 1)
        {
            //cout<<myrank<<"lr receiving "<<myright<<endl;
            MPI_Recv(&R_data_size[2], 1, MPI_LONG, myright, data_tags[0], MPI_COMM_WORLD, &status);

            
            R_myfield_liner.resize(R_data_size[2]);
       
            MPI_Recv(&R_myfield_liner.front(), R_data_size[2], MPI_Fline, \
                    myright, data_tags[2], MPI_COMM_WORLD, &status);
            //cout<<myrank<<"lr receiving complete "<<myright<<endl;
        }

        
        if(rankxi < rank_per_row - 1)
        {
            // 向右 3 * 2 个
            /// 先发送数据大小，再发送数据 
            //cout<<myrank<<"lr send to  "<<myright<<endl;
            MPI_Send(&S_data_size[2], 1, MPI_LONG, myright, data_tags[4], MPI_COMM_WORLD);
            MPI_Send(&S_myfield_liner.front(), S_data_size[2], MPI_Fline, \
                    myright, data_tags[6], MPI_COMM_WORLD);
            //cout<<myrank<<"lr send to  over "<<myright<<endl;
        }
         
        // 接收左边发来的，是左边发给右边的
        if(rankxi > 0)
        {
            //cout<<myrank<<"lr recving "<<myleft<<endl;
            MPI_Recv(&R_data_size[0], 1, MPI_LONG, myleft, data_tags[4], MPI_COMM_WORLD, &status);

            //cout<<"data size receiving "<<R_data_size[0]<<endl<<R_data_size[1]<<endl;
            
            R_myfield_linel.resize(R_data_size[0]);
            //cout<<" resizing complete "<<endl;
            
            MPI_Recv(&R_myfield_linel.front(), R_data_size[0], MPI_Fline, \
                    myleft, data_tags[6], MPI_COMM_WORLD, &status);
            //cout<<myrank<<"lr recving complete "<<myleft<<endl;
        }
        
        
        mybox.fline_copy_to(R_myfield_linel, R_myfield_liner, 0);
        clear_vec(S_myfield_linel);
        clear_vec(S_myfield_liner);
        clear_vec(R_myfield_linel);
        clear_vec(R_myfield_liner);
        MPI_Type_free(&MPI_Pline);
        MPI_Type_free(&MPI_Fline);
        MPI_Type_free(&MPI_Jline);
}




void mpi_exchange_fields_ud(const int& myrank, const int& ranksize, __Simbox& mybox,\
        long data_tags[], MPI_Status& status)
{
    //cout<<"starting ud "<<endl;
    if(ranksize < 2)
    {
        return;
    }
    int rank_per_row = ranksize / 2;
        int rankxi = myrank % rank_per_row, rankyj = myrank / rank_per_row;
        int rank_all_row = ranksize / rank_per_row;
        int myleft = myrank - 1, myright = myrank + 1;
        int myup = myrank +  rank_per_row;
        int mydown = myrank - rank_per_row; 
        MPI_Datatype MPI_Fline, MPI_Jline, MPI_Pline;
        mpi_type_commit(MPI_Pline, MPI_Fline, MPI_Jline);
        long S_data_size[8] = {};
        __Fline S_myfield_lineu, S_myfield_lined;
        __Jline S_myj_lineu, S_myj_lined;
        // 0， 1 代表沿x，y方向
        mybox.copy_to_fline(S_myfield_lined, S_myfield_lineu, 1);
        mybox.copy_to_jline(S_myj_lined, S_myj_lineu, 1);
        //cout<<"ud copyed "<<endl;
        // 次序：左，右，下，上
        S_data_size[4] = S_myfield_lined.size();
        S_data_size[5] = S_myj_lined.size();
        S_data_size[6] = S_myfield_lineu.size();
        S_data_size[7] = S_myj_lineu.size();
        // 接收
        // 也是先左，后右
        long R_data_size[8] = {};
        __Fline R_myfield_lined, R_myfield_lineu;
        __Jline R_myj_lined, R_myj_lineu;

        
        // 现在是向下    
        if(rankyj > 0)
        {
            // 向右 3 * 2 个
            /// 先发送数据大小，再发送数据 
            //cout<<myrank<<" send to  "<<mydown<<" data 50 "<<S_myj_lined[50].data_rho[0]\
                <<"\t"<<S_myj_lined[50].data_rho[1]<<endl;
            MPI_Send(&S_data_size[4], 1, MPI_LONG, mydown, data_tags[8], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[5], 1, MPI_LONG, mydown, data_tags[9], MPI_COMM_WORLD);
            MPI_Send(&S_myfield_lined.front(), S_data_size[4], MPI_Fline, \
                    mydown, data_tags[10], MPI_COMM_WORLD);
            MPI_Send(&S_myj_lined.front(), S_data_size[5], MPI_Jline, \
                    mydown, data_tags[11], MPI_COMM_WORLD);
            //cout<<myrank<<" send to  over "<<mydown<<endl;
        }
        
        // 接收上面来的
        if(rankyj < rank_all_row - 1)
        {
            //cout<<myrank<<" rec from "<<myup<<endl;
            MPI_Recv(&R_data_size[6], 1, MPI_LONG, myup, data_tags[8], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[7], 1, MPI_LONG, myup, data_tags[9], MPI_COMM_WORLD, &status);

            
            R_myfield_lineu.resize(R_data_size[6]);
            R_myj_lineu.resize(R_data_size[7]);
       
            MPI_Recv(&R_myfield_lineu.front(), R_data_size[6], MPI_Fline, \
                    myup, data_tags[10], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_myj_lineu.front(), R_data_size[7], MPI_Jline, \
                    myup, data_tags[11], MPI_COMM_WORLD, &status);
            //cout<<myrank<<" rec from  "<<myup<<" data 50 "<<R_myj_lineu[50].data_rho[0]\
                <<"\t"<<R_myj_lineu[50].data_rho[1]<<endl;
            //cout<<myrank<<" rec from complete"<<myup<<endl;
        } 
        
        
        // 现在向上
        if(rankyj < rank_all_row - 1)
        {
            /// 先发送数据大小，再发送数据 
            //cout<<myrank<<" send to "<<myup<<endl;
            MPI_Send(&S_data_size[6], 1, MPI_LONG, myup, data_tags[12], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[7], 1, MPI_LONG, myup, data_tags[13], MPI_COMM_WORLD);
            MPI_Send(&S_myfield_lineu.front(), S_data_size[6], MPI_Fline, \
                    myup, data_tags[14], MPI_COMM_WORLD);
            MPI_Send(&S_myj_lineu.front(), S_data_size[7], MPI_Jline, \
                    myup, data_tags[15], MPI_COMM_WORLD);
            //cout<<myrank<<" send to  over "<<myup<<endl;
        }
         
        if(rankyj > 0)
        {
            //cout<<myrank<<" rec from "<<mydown<<endl;
            MPI_Recv(&R_data_size[4], 1, MPI_LONG, mydown, data_tags[12], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[5], 1, MPI_LONG, mydown, data_tags[13], MPI_COMM_WORLD, &status);

            
            R_myfield_lined.resize(R_data_size[4]);
            R_myj_lined.resize(R_data_size[5]);
       
            MPI_Recv(&R_myfield_lined.front(), R_data_size[4], MPI_Fline, \
                    mydown, data_tags[14], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_myj_lined.front(), R_data_size[5], MPI_Jline, \
                    mydown, data_tags[15], MPI_COMM_WORLD, &status);
            //cout<<myrank<<" rec from over"<<mydown<<endl;
        }
        //cout<<"cping to field "<<endl;
        mybox.fline_copy_to(R_myfield_lined, R_myfield_lineu, 1);
        mybox.jline_copy_to(R_myj_lined, R_myj_lineu, 1);
        clear_vec(S_myfield_lineu);
        clear_vec(S_myj_lineu);
        clear_vec(S_myfield_lined);
        clear_vec(S_myj_lined);
        clear_vec(R_myfield_lineu);
        clear_vec(R_myj_lineu);
        clear_vec(R_myfield_lined);
        clear_vec(R_myj_lined);
        MPI_Type_free(&MPI_Pline);
        MPI_Type_free(&MPI_Fline);
        MPI_Type_free(&MPI_Jline);
}

void mpi_exchange_ptcls(const int& myrank, const int& ranksize, __Simbox& mybox,\
        long data_tags[], MPI_Status& status)
{
    if(ranksize < 2)
    {
        return;
    }
    
    int rank_per_row = ranksize;
    int rankxi = myrank % rank_per_row, rankyj = myrank / rank_per_row;
    int rank_all_row = ranksize / rank_per_row;
    int myleft = myrank - 1, myright = myrank + 1;
    int myup = myrank +  rank_per_row;
    int mydown = myrank - rank_per_row; 
    
    MPI_Datatype MPI_Pline, MPI_Fline, MPI_Jline;
    mpi_type_commit(MPI_Pline, MPI_Fline, MPI_Jline);
    long S_data_size[2] = {};
    
    __Pline S_mypdata_linel, S_mypdata_liner;
    mybox.copy_to_pline(S_mypdata_linel, S_mypdata_liner, 0);
    
    S_data_size[0] = S_mypdata_linel.size();
    S_data_size[1] = S_mypdata_liner.size();
    //cout<<rankxi<<" sending size "<<S_data_size[0]<<"\t"<<S_data_size[1]<<endl;
    long R_data_size[2] = {};
    __Pline R_mypdata_linel, R_mypdata_liner;
    // 向左两个
    
    if(myleft >= 0)
    {
        MPI_Recv(&R_data_size[0], 1, MPI_LONG, myleft, data_tags[2], MPI_COMM_WORLD, &status);
        R_mypdata_linel.resize(R_data_size[0]);
        MPI_Recv(&R_mypdata_linel.front(), R_data_size[0], MPI_Pline, \
                myleft, data_tags[3], MPI_COMM_WORLD, &status);
    }
    
    if(myright < rank_per_row)
    {
        // 向右 3 * 2 个
        /// 先发送数据大小，再发送数据 
        MPI_Send(&S_data_size[1], 1, MPI_LONG, myright, data_tags[2], MPI_COMM_WORLD);
        MPI_Send(&S_mypdata_liner.front(), S_data_size[1], MPI_Pline, \
                myright, data_tags[3], MPI_COMM_WORLD);
    }
    // 接收左边发来的，是左边发给右边的
    
         
    
    
    // 接收右边发过来，是右边发给左边的
   
    
    
    if(myleft >= 0)
    {
        MPI_Send(&S_data_size[0], 1, MPI_LONG, myleft, data_tags[0], MPI_COMM_WORLD);
        MPI_Send(&S_mypdata_linel.front(), S_data_size[0], MPI_Pline, \
                myleft, data_tags[1], MPI_COMM_WORLD);
    } 
    
    
    if(myright < rank_per_row)
    {
        MPI_Recv(&R_data_size[1], 1, MPI_LONG, myright, data_tags[0], MPI_COMM_WORLD, &status);
        R_mypdata_liner.resize(R_data_size[1]);
        MPI_Recv(&R_mypdata_liner.front(), R_data_size[1], MPI_Pline, \
                myright, data_tags[1], MPI_COMM_WORLD, &status);
    } 
    
    
    
                 
    // 接收
    // 也是先左，后右
    
    /***
    if(R_data_size[0] + R_data_size[1] != 0)
    {
        cout<<myrank<<" sending size "<<S_data_size[0]<<"\t"<<S_data_size[1]<<\
            " recv "<<R_data_size[0]<<"\t"<<R_data_size[1]<<endl;
    }
    ***/
   
    mybox.pline_copy_to(R_mypdata_linel, R_mypdata_liner, 0);
    clear_vec(S_mypdata_linel);
    clear_vec(S_mypdata_liner);
    clear_vec(R_mypdata_linel);
    clear_vec(R_mypdata_liner);
    MPI_Type_free(&MPI_Pline);
    MPI_Type_free(&MPI_Fline);
    MPI_Type_free(&MPI_Jline);
}



/***
void mpi_exchange_data(const int& myrank, const int& ranksize, __Simbox& mybox,\
        long data_tags[], MPI_Status& status)
{
        MPI_Datatype MPI_Fline, MPI_Pline, MPI_Jline;
        mpi_type_commit(MPI_Pline, MPI_Fline, MPI_Jline);
        long S_data_size[6];
        
        __Fline S_myfield_linel, S_myfield_liner;
        __Pline S_mypdata_linel, S_mypdata_liner;
        __Jline S_myj_linel, S_myj_liner;
        mybox.copy_to_fline(S_myfield_linel, S_myfield_liner, 0);
        mybox.copy_to_pline(S_mypdata_linel, S_mypdata_liner, 0);
        mybox.copy_to_jline(S_myj_linel, S_myj_liner, 0);
        //cout<<data_tags[0]<<"\t"<<data_tags[1]<<"\t"<<data_tags[2]<<"\t"<<data_tags[3]<<endl;
        
        S_data_size[0] = S_myfield_linel.size();
        S_data_size[1] = S_mypdata_linel.size();
        S_data_size[2] = S_myj_linel.size();
        S_data_size[3] = S_myfield_liner.size();
        S_data_size[4] = S_mypdata_liner.size();
        S_data_size[5] = S_myj_liner.size();
        //cout<<myrank<<" sending size\
        "<<S_data_size[0]<<"\t"<<S_data_size[1]<<"\t"<<S_data_size[2]<<"\t"<<S_data_size[3]<<endl;
        // 向左两个
        if(myrank != 0)
        {
        
            MPI_Send(&S_data_size[0], 1, MPI_LONG, myrank - 1, data_tags[0], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[1], 1, MPI_LONG, myrank - 1, data_tags[1], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[2], 1, MPI_LONG, myrank - 1, data_tags[2], MPI_COMM_WORLD);
            MPI_Send(&S_myfield_linel.front(), S_data_size[0], MPI_Fline, \
                    myrank - 1, data_tags[3], MPI_COMM_WORLD);
            MPI_Send(&S_mypdata_linel.front(), S_data_size[1], MPI_Pline, \
                    myrank - 1, data_tags[4], MPI_COMM_WORLD);
            MPI_Send(&S_myj_linel.front(), S_data_size[2], MPI_Jline, \
                    myrank - 1, data_tags[5], MPI_COMM_WORLD);
        }
        if(myrank != ranksize - 1)
        {
            // 向右 3 * 2 个
            /// 先发送数据大小，再发送数据 
            MPI_Send(&S_data_size[3], 1, MPI_LONG, myrank + 1, data_tags[6], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[4], 1, MPI_LONG, myrank + 1, data_tags[7], MPI_COMM_WORLD);
            MPI_Send(&S_data_size[5], 1, MPI_LONG, myrank + 1, data_tags[8], MPI_COMM_WORLD);
            //cout<<myrank<<" sending to right pdata size "<<S_data_size[4]<<endl;
            MPI_Send(&S_myfield_liner.front(), S_data_size[3], MPI_Fline, \
                    myrank + 1, data_tags[9], MPI_COMM_WORLD);
            MPI_Send(&S_mypdata_liner.front(), S_data_size[4], MPI_Pline, \
                    myrank + 1, data_tags[10], MPI_COMM_WORLD);
            MPI_Send(&S_myj_liner.front(), S_data_size[5], MPI_Jline, \
                    myrank + 1, data_tags[11], MPI_COMM_WORLD);
        }
            
        // 接收
        // 也是先左，后右
        long R_data_size[6];
        __Fline R_myfield_linel, R_myfield_liner;
        __Pline R_mypdata_linel, R_mypdata_liner;
        __Jline R_myj_linel, R_myj_liner;
        // 接收左边发来的，是左边发给右边的
        if(myrank != 0)
        {
            //cout<<myrank<<" recving"<<endl;
            //cout<<myrank<<" recving with tag "<<data_tags[4]<<" from "<<myrank - 1<<endl;
            MPI_Recv(&R_data_size[0], 1, MPI_LONG, myrank - 1, data_tags[6], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[1], 1, MPI_LONG, myrank - 1, data_tags[7], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[2], 1, MPI_LONG, myrank - 1, data_tags[8], MPI_COMM_WORLD, &status);

            //cout<<"data size receiving "<<R_data_size[0]<<endl<<R_data_size[1]<<endl;
            
            R_myfield_linel.resize(R_data_size[0]);
            R_mypdata_linel.resize(R_data_size[1]);
            R_myj_linel.resize(R_data_size[2]);
            //cout<<" resizing complete "<<endl;
            
            MPI_Recv(&R_myfield_linel.front(), R_data_size[0], MPI_Fline, \
                    myrank - 1, data_tags[9], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_mypdata_linel.front(), R_data_size[1], MPI_Pline, \
                    myrank - 1, data_tags[10], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_myj_linel.front(), R_data_size[2], MPI_Jline, \
                    myrank - 1, data_tags[11], MPI_COMM_WORLD, &status);
            // 接收右边发过来，是右边发给左边的
            //cout<<"rank "<<myrank<<" rev l complete"<<endl;
        }
        if(myrank != ranksize - 1)
        {
            //cout<<myrank<<" recving with tag "<<data_tags[0]<<" from "<<myrank + 1<<endl;
            //cout<<myrank<<" recving with tag "<<data_tags[1]<<" from "<<myrank + 1<<endl;
            MPI_Recv(&R_data_size[3], 1, MPI_LONG, myrank + 1, data_tags[0], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[4], 1, MPI_LONG, myrank + 1, data_tags[1], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_data_size[5], 1, MPI_LONG, myrank + 1, data_tags[2], MPI_COMM_WORLD, &status);

            
            R_myfield_liner.resize(R_data_size[3]);
            R_mypdata_liner.resize(R_data_size[4]);
            R_myj_liner.resize(R_data_size[5]);
       
            //cout<<myrank<<" recving with tag "<<data_tags[2]<<" from "<<myrank + 1<<endl;
            MPI_Recv(&R_myfield_liner.front(), R_data_size[3], MPI_Fline, \
                    myrank + 1, data_tags[3], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_mypdata_liner.front(), R_data_size[4], MPI_Pline, \
                    myrank + 1, data_tags[4], MPI_COMM_WORLD, &status);
            MPI_Recv(&R_myj_liner.front(), R_data_size[5], MPI_Jline, \
                    myrank + 1, data_tags[5], MPI_COMM_WORLD, &status);
            //cout<<"data size receiving "<<R_myfield_liner.size()<<endl<<R_data_size[2]<<endl;
            //path 到field 和cell中去
            //cout<<"rank "<<myrank<<" rev r complete"<<endl;
        }
        //cout<<myrank<<" sending size "<<S_data_size[0]<<"\t"<<S_data_size[1]<<\
        "\t"<<S_data_size[2]<<"\t"<<S_data_size[3]<<endl;
        mybox.fline_copy_to(R_myfield_linel, R_myfield_liner, 0);
        mybox.pline_copy_to(R_mypdata_linel, R_mypdata_liner, 0);
        mybox.jline_copy_to(R_myj_linel, R_myj_liner, 0);
        MPI_Type_free(&MPI_Pline);
        MPI_Type_free(&MPI_Fline);
        MPI_Type_free(&MPI_Jline);
}
***/
#endif
